#define _USE_MATH_DEFINES
#include <iostream>
#include <fstream>
#include <vector>
#include <cmath>
#include <Eigen\Dense>
#include <math.h>

using namespace std;
using namespace Eigen;

#define DIM 16

#define TOTAL_TIME 1.0
#define SIMULATION_DELT 2.5E-6
#define SIMULATION_AMOUNT 4E5

#define NODE_NUM_AC 18
#define BRANCH_NUM_AC 36
#define NODE_NUM_DC 4
#define BRANCH_NUM_DC 9
#define NODE_NUM 24
#define BRANCH_NUM 54

#define PI acos(-1.0)
#define sqrt_2 1.4142135623730951
#define sqrt_3 1.7320508075688772

class Capacitor
{
public:
	double cap_g;
	double cap_v;
	double cap_ib;
	double cap_jh;
};

//Inductor
class Inductor
{
public:
	double ind_g;
	double ind_v;
	double ind_ib;
	double ind_jh;
};

class Switch
{
public:
	double g;
	double gon;
	double goff;
};

class VSC
{
public:
	double g_vsc;
	double gon_vsc;
	double goff_vsc;
	double g_snubber;

};

//Transformer
static double* d_G_trans;
static double* d_parB_trans;
static double* d_J_trans_A_PVunit_d;
static double* d_J_trans_B_PVunit_d;
static double* d_J_trans_C_PVunit_d;

static double* I_port_A_PVunit;
static double* I_port_B_PVunit;
static double* I_port_C_PVunit;

//Y Calculation (DCside)
static Matrix <double, NODE_NUM_DC, BRANCH_NUM_DC> A2;
static Matrix <double, BRANCH_NUM_DC, BRANCH_NUM_DC> Yg2[DIM];
static Matrix <double, NODE_NUM_DC, 1> V_DC[DIM];

//Y Calculation (ACside)
static Matrix <double, NODE_NUM_AC, BRANCH_NUM_AC> A1;
static Matrix <double, BRANCH_NUM_AC, BRANCH_NUM_AC> Yg1[DIM];

static Matrix <double, NODE_NUM_AC - 3, 3> Y21[DIM];
static Matrix <double, NODE_NUM_AC - 3, NODE_NUM_AC - 3> Y22_inv[DIM];
static Matrix <double, NODE_NUM_AC - 3, 1> Jin[DIM];

//指针空间
static double** d_A1_d;
static double** d_A2_d;
static double** d_Yg1_d;
static double** d_Yg2_d;
static double** d_AYg1_d;
static double** d_AYg2_d;
static double** d_Y1_d;
static double** d_Y2_d;
static double** d_J_branch1_d;
static double** d_J_branch2_d;
static double** d_J1_d;
static double** d_J2_d;

static double** d_Y11_d;
static double** d_Y12_d;
static double** d_Y21_d;
static double** d_Y22_d;
static double** d_Y22_inv_d;

static double** d_Jex_d;
static double** d_Jin_d;

static double** d_Yeq_d;
static double** d_Jeq_d;
static double** d_YY_d;
static double** d_YYY_d;
static double** d_YYJ_d;
static double** d_Vin_d;
static double** d_Vex_d;
static double** d_YV_d;
static double** d_JYV_d;

static double** d_V_DC_d;
static double** d_Y2_inv_d;

//Fault
class Fault
{
public:
    double g_fault;
    double g_on;
    double g_off;
};

//PImodel
class PImodel
{
public:
    double GC, GCm, G_series_s, G_series_m;
    double R_cal_s, R_cal_m;
    double G_PImodel[6][6];
};

//Transformer
static double* d_G_trans_sys;
static double* d_parB_trans_sys;
static double* d_J_trans_A_sys_d;
static double* d_J_trans_B_sys_d;
static double* d_J_trans_C_sys_d;

//PImodel_1
static double* d_Ih_mutual1_1;
static double* d_Ih_mutual2_1;
static double* d_Ih_self1_1;
static double* d_Ih_self2_1;
static double* d_Ih_ABC_1;

//PImodel_2
static double* d_Ih_mutual1_2;
static double* d_Ih_mutual2_2;
static double* d_Ih_self1_2;
static double* d_Ih_self2_2;
static double* d_Ih_ABC_2;

//Y Calculation
static Matrix <double, NODE_NUM, BRANCH_NUM> A_CAL;

static double* d_A_CAL_d;
static double* d_Yg_CAL_d;
static double* d_AYg_CAL_d;
static double* d_Y_CAL_d;
static double* d_J_branch_CAL_d;
static double* d_J_CAL_d;

static double* d_Y_total_d;
static double* d_J_total_d;
static double* d_Y_total_inv_d;
static double* d_V_total_d;

class PI_model 
{
public:
	// Current State
    int k1, k2, k3, k4, k5, k6, k7, k8;
    int k9, k10, k11;
    double Y1, Y4, Y5, Y6, Y7, Y8, Y9;
    double Y2, Y3, Y10;
    double T1;
    double PI_OUT;

    // History
    double Y1_his;
    double Y4_his;
    double Y5_his;
    double Y6_his;
    double Y9_his;
    double Y8_his;
    double Y7_his;
};

class PLL3Phase
{
public:
	//Parameters
    double dt;
    double Base;
    double PIPG;
    double PIIT;
    double Frat;
    double Fmax;
    double Fmin;
    double fc;

    double Fmax1;
    double Fmin1;

    double Tf;
    double Kf;
    
    //History
    double PHI_his = 0.0;
    double input_integral_old = 0.0;
    double output_integral_old = 0.0;
    double Err_input_old = 0.0;
    double Err_integral_old = 0.0;
    double vd1_1_his = 0.0;
    double vq1_1_his = 0.0;
    double vd2_1_his = 0.0;
    double vq2_1_his = 0.0;

    //LPF History Values
    double LPF1_input_his = 0.0;
    double LPF1_output_his = 0.0;
    double LPF2_input_his = 0.0;
    double LPF2_output_his = 0.0;
    double LPF3_input_his = 0.0;
    double LPF3_output_his = 0.0;
    double LPF4_input_his = 0.0;
    double LPF4_output_his = 0.0;

    //OUTPUT
    double output;
};

class MPPT
{
public:
	//Histroy
    int StartBlk = 0;
    int Reset_old = 0;
    double Vold = 0;
    double Iold = 0;
    double Vmppt_old = 0;

    int SampleCount;
    int StrtupCount;
    int output_SampNum;
    int output_StrtupNum;

  

    //OUTPUT
    double output;
    double output_Vmppt;
    int output_State;
    double output_Vopen;
    double output_VstartStep;
    double Cond; 
};

